<!doctype html>
<html lang="zh-cn">
<head>

    <meta charset="utf-8">
    <meta name="generator" content="Hugo 0.57.2" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Nginx | The Sky of OtsWang</title>
    <meta property="og:title" content="Nginx - The Sky of OtsWang">
    <meta property="og:type" content="article">
        
    <meta property="article:published_time" content="2019-01-04T10:31:57&#43;08:00">
        
        
    <meta property="article:modified_time" content="2019-01-04T10:31:57&#43;08:00">
        
    <meta name="Keywords" content="golang,go语言,otswang,java,博客,python">
    <meta name="description" content="Nginx">
        
    <meta name="author" content="OtsWang">
    <meta property="og:url" content="https://otswang.gitee.io/hugo/post/middle_tools/nginx/">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">

    <link rel="stylesheet" href="/hugo/css/normalize.css">
    
        <link rel="stylesheet" href="/hugo/css/prism.css">
    
    <link rel="stylesheet" href="/hugo/css/style.css">
    <script type="text/javascript" src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>

    


    
    
</head>

<body>
<header id="header" class="clearfix">
    <div class="container">
        <div class="col-group">
            <div class="site-name ">
                
                    <a id="logo" href="https://otswang.gitee.io/hugo/">
                        The Sky of OtsWang
                    </a>
                
                <p class="description">擅长写HelloWorld的小小码农</p>
            </div>
            <div>
                <nav id="nav-menu" class="clearfix">
                    
                    
                    <a  href="https://otswang.gitee.io/hugo/" title="Home">Home</a>
                    
                    <a  href="https://otswang.gitee.io/hugo/tags/" title="Tags">Tags</a>
                    
                    <a  href="https://otswang.gitee.io/hugo/categories/" title="Categories">Categories</a>
                    
                    <a  href="https://otswang.gitee.io/hugo/archives/" title="Archives">Archives</a>
                    
                    <a  href="https://otswang.gitee.io/hugo/about/" title="About">About</a>
                    
                </nav>
            </div>
        </div>
    </div>
</header>


<div id="body">
    <div class="container">
        <div class="col-group">

            <div class="col-8" id="main">
                <div class="res-cons">
                    <article class="post">
                        <header>
                            <h1 class="post-title">Nginx</h1>
                        </header>
                        <date class="post-meta meta-date">
                            2019年1月4日
                        </date>
                        
                        <div class="post-meta">
                            <span>|</span>
                            
                                <span class="meta-category"><a href="https://otswang.gitee.io/hugo/categories/middletools">MiddleTools</a></span>
                            
                        </div>
                        
                        
                        
                        <div class="post-content">
                            <p>Nginx 日常积累</p>

<h2 id="location-的使用">location 的使用</h2>

<pre><code class="language-config">server {
    server_name otswang.win
    location /admin/ {

    }

// 完全匹配， otswang.win/adc √ otswang.win/adc/ ×
    location = /adc {
        [...]
    }

// 前缀匹配下，返回最长匹配的 location，与 location 所在位置顺序无关
// curl -I otswang.win/document http/1.1 701
    location /doc {
        return 702;
    }
    location /docu {
        return 701;
    }

// 此时返回 701 ，当位置互换后，则返回702
    location ~ ^/doc[a-z]+ {
        return 701;
    }

    location ~ ^/docu[a-z]+ {
        return 702;
    }

}
</code></pre>

<p>location 支持的语法有： <code>location [=|~|~*|^~|@] pattern { ... }</code></p>

<pre><code>= 完全匹配
~ 区分大小写的正则匹配
~* 不区分大小写的正则匹配
^~ 前缀匹配 如果该location是最佳匹配，该修饰符将不再进行正则检测
</code></pre>

<p>当有多条 location 规则时，nginx 有一套比较复杂的规则，优先级如下：</p>

<ul>
<li>精确匹配 =</li>
<li>前缀匹配 ^~（立刻停止后续的正则搜索）</li>
<li>按文件中顺序的正则匹配 ~或~*</li>
<li>匹配不带任何修饰的前缀匹配。</li>
</ul>

<h2 id="日志配置">日志配置</h2>

<pre><code class="language-conf">log_format main '$remote_addr &quot;$time_iso8601&quot; &quot;$request&quot; $status $body_bytes_sent &quot;$http_user_agent&quot; &quot;$http_referer&quot; &quot;$http_x_forwarded_for&quot; &quot;$request_time&quot; &quot;$upstream_response_time&quot; &quot;$http_cookie&quot; &quot;$http_Authorization&quot; &quot;$http_token&quot;';
access_log  /var/log/nginx/example.access.log  main;
</code></pre>

<h2 id="nginx与限流">Nginx与限流</h2>

<h3 id="基本限流算法">基本限流算法</h3>

<p>常用的限流算法有计数器、漏桶算法和令牌桶算法。</p>

<p>计数器的方式比较简单粗暴，使用一个计数器，对一个接口的每次访问都会令此计数加一，如果超过了设置的连接数，则放弃其余的请求，此时会出现边界问题。</p>

<p>漏桶算法使用恒定的输出速率r，当桶中没有连接时，输出速率为0，当桶中有连接时，输出速率为r，如果连接数大于桶的容量，则会溢出。</p>

<p>令牌桶算法是系统会以恒定的速率r产生令牌，当请求到来时，如果有充足的令牌，则每个请求会获取一个令牌，如果令牌不足，则请求无法获取令牌，会被丢弃。</p>

<p>漏桶算法的处理速率为0或者r，而令牌桶算法的速率则可能比r大。</p>

<p><strong>Nginx的限流</strong></p>

<p>Nginx主要有两种限流方式：按连接数限流(ngx_http_limit_conn_module)、按请求速率限流(ngx_http_limit_req_module)；</p>

<p>官方文档：</p>

<h3 id="ngx-http-limit-req-module">ngx_http_limit_req_module</h3>

<p>The <code>ngx_http_limit_req_module</code> module (0.7.21) is used to limit the request processing rate per a defined key, in particular, the processing rate of requests coming from a <strong>single IP address</strong>. The limitation is done using the “leaky bucket” method.</p>

<p>Example Configuration</p>

<pre><code class="language-conf">http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    ...

    server {

        ...

        location /search/ {
            limit_req zone=one burst=5;
        }
</code></pre>

<p><code>limit_req zone=name [burst=number] [nodelay | delay=number];</code></p>

<p>Sets the shared memory zone and the maximum burst size of requests. If the requests rate exceeds the rate configured for a zone, their processing is delayed such that requests are processed at a defined rate. Excessive requests are delayed until their number exceeds the maximum burst size in which case the request is terminated with an error. By default, the maximum burst size is equal to zero.</p>

<p>If delaying of excessive requests while requests are being limited is not desired, the parameter nodelay should be used:<code>limit_req zone=one burst=5 nodelay;</code></p>

<p>The <code>delay</code> parameter (1.15.7) specifies a limit at which excessive requests become delayed. Default value is zero, i.e. all excessive requests are delayed.</p>

<p>There could be several <code>limit_req</code> directives. For example, the following configuration will limit the processing rate of requests coming from a single IP address and, at the same time, the request processing rate by the virtual server:</p>

<pre><code class="language-conf">    limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
    limit_req_zone $server_name zone=perserver:10m rate=10r/s;

    server {
        ...
        limit_req zone=perip burst=5 nodelay;
        limit_req zone=perserver burst=10;
    }
</code></pre>

<p>Other directives:</p>

<p>limit_req_log_level info | notice | warn | error;
limit_req_status code;</p>

<p>Note that instead of $remote_addr, the $binary_remote_addr variable is used here. The $binary_remote_addr variable’s size is always 4 bytes for IPv4 addresses or 16 bytes for IPv6 addresses. The stored state always occupies 64 bytes on 32-bit platforms and 128 bytes on 64-bit platforms. One megabyte zone can keep about 16 thousand 64-byte states or about 8 thousand 128-byte states.</p>

<p>If the zone storage is exhausted, the least recently used(<strong>LRU</strong>) state is removed. Even if after that a new state cannot be created, the request is terminated with an error.</p>

<p>The rate is specified in requests per second (r/s). If a rate of less than one request per second is desired, it is specified in request per minute (r/m). For example, half-request per second is 30r/m.</p>

<h3 id="ngx-http-limit-conn-module">ngx_http_limit_conn_module</h3>

<p>The <code>ngx_http_limit_conn_module</code> module is used to limit the number of connections per the defined key, in particular, the number of connections from a single IP address.</p>

<p>Not all connections are counted. A connection is counted only if it has a request being processed by the server and the whole request header has already been read.</p>

<p>Example Configuration</p>

<pre><code class="language-conf">    http {
        limit_conn_zone $binary_remote_addr zone=addr:10m;

        ...

        server {

            ...

            location /download/ {
                limit_conn addr 1;
            }
</code></pre>

<p>Directives: <code>limit_conn zone number;</code>Sets the shared memory zone and the maximum allowed number of connections for a given key value. When this limit is exceeded, the server will return the error in reply to a request. For example, the directives above allow only one connection per an IP address at a time.</p>

<pre><code>In HTTP/2 and SPDY, each concurrent request is considered a separate connection. 
</code></pre>

<p>There could be several <code>limit_conn</code> directives. For example, the following configuration will limit the number of connections to the server per a client IP and, at the same time, the total number of connections to the virtual server:</p>

<pre><code class="language-conf">    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;

    server {
        ...
        limit_conn perip 10;
        limit_conn perserver 100;
    }
</code></pre>

<p>Other directives:</p>

<p><code>limit_conn_log_level info | notice | warn | error;</code></p>

<p><code>limit_conn_status code;</code></p>

<p><code>limit_zone name $variable size;</code></p>

<p>This directive was made obsolete(老式的；废弃的) in version 1.1.8 and was removed in version 1.7.6. An equivalent limit_conn_zone directive with a changed syntax should be used instead:<code>limit_conn_zone $variable zone=name:size;</code></p>

<h2 id="nginx后端健康监测">Nginx后端健康监测</h2>

<p>严格来说，nginx是没有针对负载均衡后端节点的健康检查的，但是可以通过<code>proxy_next_upstream</code>来间接实现，但这个还是会把请求转发给故障服务器的，然后再转发给别的服务器，这样就浪费了一次转发。</p>

<p><code>nginx_upstream_check_module</code>为淘宝技术团队开发的nginx模快，用来检测后方server的健康状态，如果后端服务器不可用，则所以的请求不转发到这台服务器。</p>
                        </div>

                        


                        


                        <div class="post-meta meta-tags">
                            
                            <ul class="clearfix">
                                
                                <li><a href="https://otswang.gitee.io/hugo/tags/nginx">Nginx</a></li>
                                
                                <li><a href="https://otswang.gitee.io/hugo/tags/%E9%99%90%E6%B5%81">限流</a></li>
                                
                            </ul>
                            
                        </div>
                    </article>
                    
    

    
    
                </div>
            </div>
            <div id="secondary">

    <section class="widget">
        <form id="search" action="//www.google.com/search" method="get" accept-charset="utf-8" target="_blank" _lpchecked="1">
      
      <input type="text" name="q" maxlength="20" placeholder="Search">
      <input type="hidden" name="sitesearch" value="https://otswang.gitee.io/hugo/">
      <button type="submit" class="submit icon-search"></button>
</form>
    </section>

    
    <div class="clear">
        <div class="toc-article">
            <div class="toc-title">文章目录</dixsv>
            <nav id="TableOfContents">
<ul>
<li>
<ul>
<li><a href="#location-的使用">location 的使用</a></li>
<li><a href="#日志配置">日志配置</a></li>
<li><a href="#nginx与限流">Nginx与限流</a>
<ul>
<li><a href="#基本限流算法">基本限流算法</a></li>
<li><a href="#ngx-http-limit-req-module">ngx_http_limit_req_module</a></li>
<li><a href="#ngx-http-limit-conn-module">ngx_http_limit_conn_module</a></li>
</ul></li>
<li><a href="#nginx后端健康监测">Nginx后端健康监测</a></li>
</ul></li>
</ul>
</nav>
        </div>
    </div>
    

</div>
        </div>
    </div>
</div>
<footer id="footer">
    <div class="container">
        &copy; 2020 <a href="https://otswang.gitee.io/hugo/">The Sky of OtsWang By OtsWang</a>.
        Powered by <a rel="nofollow noreferer noopener" href="https://gohugo.io" target="_blank">Hugo</a>.
        <a href="https://www.flysnow.org/" target="_blank">Theme</a> based on <a href="https://github.com/Dudiao137/maupassant-hugo" target="_blank">maupassant-ots</a>.
        
    </div>
</footer>


    <script type="text/javascript">
    
    (function(){
        $("pre code").parent().addClass("line-numbers")
    }())

    window.MathJax = {
        tex2jax: {
            inlineMath: [ ['$','$'] ],
            processEscapes: true
        }
    };
    </script>
    <script type="text/javascript" src="/hugo/js/prism.js" async="true"></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML' async></script>

<a id="rocket" href="#top"></a>
<script type="text/javascript" src="/hugo/js/totop.js?v=0.0.0" async=""></script>







 
 <script src="https://mermaidjs.github.io/scripts/mermaid.min.js"></script>
 <script>
       mermaid.initialize({ startOnLoad: true });
 </script>
</body>
</html>
